package com.view.main;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import com.coder.genreatetools.model.TableInfo;
import com.coder.genreatetools.service.DbMetaData;
import com.coder.genreatetools.util.Constants;
import com.coder.genreatetools.util.JDBCUtil;
import com.coder.genreatetools.util.TableInfoFactoty;
import com.view.main.db.DbType;
import com.view.main.table.DDLExportTableModel;
import com.view.main.table.MutiTable;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

/**
 * @version v1.0
 */
public class GeneraterMain extends JFrame {
	private static final long serialVersionUID = -1849662112222460844L;
	private MutiTable table;// 表格部分
	private Container contioner;// 根容器，采用border布局
	private Connection connection; // 数据库连接
	private DbMetaData tableInfoMetaData;// 数据库的元数据信息
	List<TableInfo> tableInfos;

	public GeneraterMain(final Connection conn, DbType dbType) {
		this(Constants.PROJECT_TITLE_INFO);
		table = new MutiTable();
		contioner = getContentPane();//创建一个根容器类的实例
		this.connection = conn; //向根容器赋值
		//向根容器添加一个组件(容器)
		contioner.add(new CheckBoxPanel(), BorderLayout.SOUTH); 

		try {
			//设置表格自定义数据模型
			table.setModel(new DDLExportTableModel());
			//设置标题带有复选框的列
			table.setCheckHeaderColumn(0);
		} catch (Exception e) {
			e.printStackTrace();
		}
		tableInfoMetaData = TableInfoFactoty.getDbMetaData(connection, dbType,Constants.DB_NAME);
		tableInfos = tableInfoMetaData.getAllTableInfo();
		//处理 所得到的 数据库中所有表的 元信息
		processDate();
		BorderLayout borderLayout = new BorderLayout(10, 10);
		//将 根容器 设置为 边界布局(包含五区:南(NORTH)、北(SOUTH)、东(EAST)、西(WEST)、中间(RENTER))
		contioner.setLayout(borderLayout);
		//向 根容器 的中间区域 添加一个 面板组件
		contioner.add(getSouthPanel(), BorderLayout.CENTER);
	}

	private List<String> checkList;
	private CheckBoxPanel checkBoxPanel;
	private JTextField pathField, packageField;

	private JPanel getSouthPanel() {
		//FlowLayout 为 流式布局；组件安装加入的先后顺序，按照设置的对齐方式从左到右排列
		JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		p.setPreferredSize(new Dimension(150, 200)); //设置组件的大小
		p.setBounds(0, 0, 200, 200);
		BoxLayout boxLayout = new BoxLayout(p, BoxLayout.Y_AXIS);
		p.setLayout(boxLayout);

		JPanel line1 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		line1.add(new JLabel("选择要生成的内容："));
		checkBoxPanel = new CheckBoxPanel();
		line1.add(checkBoxPanel);
		JPanel line2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		line2.add(new JLabel("输入要生成JAVA类的包名："+Constants.BASE_PACKAGE_NAME));
		line2.add(packageField = new JTextField("", 20));
		line2.add(new JLabel("(例如：cn.com.ixiaofu)"));

		JPanel line3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		line3.add(new JLabel("生 成 文 件 的输出目录："));
		line3.add(pathField = new JTextField(30));
		JButton browse = new JButton("浏览");
		browse.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				JFileChooser chooser = new JFileChooser();
				chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				if (chooser.showOpenDialog(GeneraterMain.this) == JFileChooser.APPROVE_OPTION) {
					pathField.setText(chooser.getSelectedFile().getAbsolutePath());
				}
			}
		});
		line3.add(browse);

		p.add(line1);
		p.add(line2);
		p.add(line3);

		JButton button = new JButton("生成");
		button.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				checkList = checkBoxPanel.getCheckList();
				if (checkList.size() == 0) {
					JOptionPane.showMessageDialog(null, "请选择要生成的项");
					return;
				}
				if (null == pathField.getText() || "" == pathField.getText().trim()) {
					JOptionPane.showMessageDialog(null, "请选择输出的目录");
					return;
				}
//				if (null == packageField.getText() || 0 == packageField.getText().trim().length()) {
//					JOptionPane.showMessageDialog(null, "请输入模块名称");
//					return;
//				}
				
				String path = pathField.getText().replace("\\", "/") + File.separator + "生成的代码" + File.separator;
				generateFile(connection, packageField.getText(), path, Constants.DB_NAME, checkList);
				JOptionPane.showMessageDialog(null, "生成完成");

				try {
					Desktop.getDesktop().open(new File(path));
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}
		});
		p.add(button);
		p.add(new JPanel());

		JPanel rightPanel = new JPanel(new BorderLayout(0, 10));
		rightPanel.add(new JScrollPane(table));
		rightPanel.add(p, BorderLayout.SOUTH);
		return rightPanel;

	}

	public GeneraterMain(String title) throws HeadlessException {
		super(title);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setSize(800, 500);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				JDBCUtil.free(connection);// 窗口关闭释放数据库连接
				System.out.println("连接释放2");
			}
		});
	}

	private void processDate() {
		int size = tableInfos.size();
		Object[][] dataObjects = new Object[size][4];
		for (int i = 0; i < size; i++) {
			dataObjects[i] = new Object[] { true, tableInfos.get(i).getTableName(), tableInfos.get(i).getTableRemark(),
					tableInfos.get(i).getTablePk() };
		}
		try {
			//更新MutiTable 数据
			table.refreshContents(dataObjects);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void generateFile(Connection connection, String packageName, String path, String dbName,List<String> checkList) {

		String packagePath = packageName.replace(".", File.separator);
		List<TableInfo> list= new ArrayList<TableInfo>(); 
		try {
			Configuration configuration = new Configuration();
			configuration.setObjectWrapper(new DefaultObjectWrapper());
			configuration.setDefaultEncoding("UTF-8");
			configuration.setClassForTemplateLoading(this.getClass(), "/");

			for(int i : table.getAllCheckedRows()){
				TableInfo tableInfo = tableInfos.get(i);
				list.add(tableInfo);
			}
			
			for (int i = 0;i < list.size();i++) {
				TableInfo tableInfo = list.get(i);
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("tableInfo", tableInfo);
				
				if(null != packageName && !"".equals(packageName)){
					map.put("packageName", Constants.BASE_PACKAGE_NAME+"."+packageName);
				}else{
					map.put("packageName", Constants.BASE_PACKAGE_NAME);
				}
				
				
				if (checkList.contains(CheckBoxPanel.JAVA)) {
					
					String javaPath = path + File.separator + Constants.GENERATE_PATH.JAVA_GENERATE_PATH + File.separator + packagePath + File.separator + "entity";
					new File(javaPath).mkdirs();
					
					Template javaTemplate = configuration.getTemplate("javaClass.ftl");
					Writer writer = new OutputStreamWriter(new FileOutputStream(javaPath + File.separator
							+ tableInfo.getTableClassName() + ".java"), "UTF-8");
					javaTemplate.process(map, writer);
					writer.close();
					
					//javaExample
					Template javaExampleTemplate = configuration.getTemplate("javaClassExample.ftl");
					Writer javaExampleWriter = new OutputStreamWriter(new FileOutputStream(javaPath + File.separator
							+ tableInfo.getTableClassName() + "Example.java"), "UTF-8");
					javaExampleTemplate.process(map, javaExampleWriter);
					javaExampleWriter.close();
				}

//				//dao 
//				if (checkList.contains(CheckBoxPanel.DAO)) {
//					Template daoTemplate = configuration.getTemplate("daoClass.ftl");
//					Writer daoWriter = new OutputStreamWriter(new FileOutputStream(daoPath + File.separator
//							+tableInfo.getTableClassName() + "Dao.java"), "UTF-8");
//					daoTemplate.process(map, daoWriter);
//					daoWriter.close();
//					
//					//daoImpl 
//					Template daoImplTemplate = configuration.getTemplate("daoImplClass.ftl");
//					Writer daoImplWriter = new OutputStreamWriter(new FileOutputStream(daoImplPath + File.separator
//							+ tableInfo.getTableClassName() + "DaoImpl.java"), "UTF-8");
//					daoImplTemplate.process(map, daoImplWriter);
//					
//					daoImplWriter.close();
//				}
				
				//dao 
				if (checkList.contains(CheckBoxPanel.DAO)) {
					String daoPath = path + File.separator + Constants.GENERATE_PATH.JAVA_GENERATE_PATH + File.separator + packagePath + File.separator + "dao";
					new File(daoPath).mkdirs();
					
//					daoImplPath = path + File.separator + Constants.GENERATE_PATH.JAVA_GENERATE_PATH + File.separator + packagePath + File.separator + "dao"+ File.separator +"impl";
//					new File(daoImplPath).mkdirs();
					
					Template daoTemplate = configuration.getTemplate("daoMapper.ftl");
					Writer daoWriter = new OutputStreamWriter(new FileOutputStream(daoPath + File.separator
							+tableInfo.getTableClassName() + "Mapper.java"), "UTF-8");
					daoTemplate.process(map, daoWriter);
					daoWriter.close();
				}
				
				//Service 
				if (checkList.contains(CheckBoxPanel.SERVICE)) {
					String servicePath = path + File.separator + Constants.GENERATE_PATH.JAVA_GENERATE_PATH + File.separator + packagePath + File.separator + "service";
					new File(servicePath).mkdirs();
					
					String serviceImplPath = path + File.separator + Constants.GENERATE_PATH.JAVA_GENERATE_PATH + File.separator + packagePath + File.separator + "service"+ File.separator +"impl";
					new File(serviceImplPath).mkdirs();
					
					Template serviceTemplate = configuration.getTemplate("serviceClass.ftl");
					Writer serviceWriter = new OutputStreamWriter(new FileOutputStream(servicePath + File.separator
							+tableInfo.getTableClassName() + "Service.java"), "UTF-8");
					serviceTemplate.process(map, serviceWriter);
					serviceWriter.close();
					
					//ServiceImpl
					Template serviceImplTemplate = configuration.getTemplate("serviceImplClass.ftl");
					Writer serviceImplWriter = new OutputStreamWriter(new FileOutputStream(serviceImplPath + File.separator
							+ tableInfo.getTableClassName() + "ServiceImpl.java"), "UTF-8");
					serviceImplTemplate.process(map, serviceImplWriter);
					
					serviceImplWriter.close();
				}			
				
				
				if (checkList.contains(CheckBoxPanel.ACTION)) {
					String actionPath = path + File.separator + Constants.GENERATE_PATH.JAVA_GENERATE_PATH + File.separator + packagePath + File.separator + "controller";
					new File(actionPath).mkdirs();
					
					Template actionTemplate = configuration.getTemplate("actionClass.ftl");
					Writer actionWriter = new OutputStreamWriter(new FileOutputStream(actionPath + File.separator
							+ tableInfo.getTableClassName() + "Controller.java"), "UTF-8");
					actionTemplate.process(map, actionWriter);
					actionWriter.close();
				}
				
				if (checkList.contains(CheckBoxPanel.IBATIS)) {
					String ibatisPath = path + File.separator + Constants.GENERATE_PATH.IBATIS_GENERATE_PATH + File.separator + packagePath;
					new File(ibatisPath).mkdirs();
					
//					Template ibatisTemplate = configuration.getTemplate("ibatisXml.ftl");
//					Writer ibatisWriter = new OutputStreamWriter(new FileOutputStream(ibatisPath + File.separator
//							+ tableInfo.getTableClassName()+ ".xml"), "UTF-8");
//					ibatisTemplate.process(map, ibatisWriter);
//					ibatisWriter.close();
					
					Template mybatisTemplate = configuration.getTemplate("mybatisXml.ftl");
					Writer mybatisWriter = new OutputStreamWriter(new FileOutputStream(ibatisPath + File.separator
							+ tableInfo.getTableClassName()+ "Mapper.xml"), "UTF-8");
					mybatisTemplate.process(map, mybatisWriter);
					mybatisWriter.close();
//					
				}
				
				if (checkList.contains(CheckBoxPanel.JSP)) {
					String jspPath =path + File.separator + Constants.GENERATE_PATH.JSP_GENERATE_PATH+ File.separator + tableInfo.getObjectBeanName();
					new File(jspPath).mkdirs();
					
					Template jspTemplate = configuration.getTemplate("jsp.ftl");
					Writer jspWriter = new OutputStreamWriter(new FileOutputStream(jspPath + File.separator
							/*+ tableInfo.getTableClassName() */+ "list.jsp"), "UTF-8");
					jspTemplate.process(map, jspWriter);
					jspWriter.close();
				}

				if (checkList.contains(CheckBoxPanel.XUTILS)) {
					
					String xUtilsPath = path + "xUtils" + File.separator + packagePath;
					new File(xUtilsPath).mkdirs();
					
					Template xUtilsTemplate = configuration.getTemplate("xUtilsClass.ftl");
					Writer xUtilsWriter = new OutputStreamWriter(new FileOutputStream(xUtilsPath + File.separator
							+ tableInfo.getTableClassName() + ".java"), "UTF-8");
					xUtilsTemplate.process(map, xUtilsWriter);
					xUtilsWriter.close();
				}
			}
			
			Map<String, Object> configmap = new HashMap<String, Object>();
			configmap.put("tableInfos", list);
			configmap.put("packageName", Constants.BASE_PACKAGE_NAME +  "." +packageName);
			//spring 层
			if (checkList.contains(CheckBoxPanel.SPRING)) {
				String springPath =path + File.separator + Constants.GENERATE_PATH.SPRING_GENERATE_PATH;
				new File(springPath).mkdirs();
				
				Template serviceImplTemplate = configuration.getTemplate("spring.ftl");//获取模板
				Writer springWriter = new OutputStreamWriter(new FileOutputStream(springPath + File.separator +"spring-"+ packageName +".xml"), "UTF-8");
				serviceImplTemplate.process(configmap, springWriter);
				springWriter.close();
			}
			
			//struts 层
			if (checkList.contains(CheckBoxPanel.SPRING)) {
				String strutsPath =path + File.separator + Constants.GENERATE_PATH.STRUTS_GENERATE_PATH;
				new File(strutsPath).mkdirs();
				
				Template serviceImplTemplate = configuration.getTemplate("struts-xml.ftl");//获取模板
				Writer strutsWriter = new OutputStreamWriter(new FileOutputStream(strutsPath + File.separator 	+"struts-"+ packageName +".xml"), "UTF-8");
				serviceImplTemplate.process(configmap, strutsWriter);
				strutsWriter.close();
			}

			if (checkList.contains(CheckBoxPanel.DOC)) {
				String docPath = path + "数据库文档";
				new File(docPath).mkdirs();
				
				Template wordTemplate = configuration.getTemplate("word_template.ftl");
				Writer wordWrite = new OutputStreamWriter(new FileOutputStream(docPath + File.separator + "数据库文档.doc"));
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("infoList", tableInfos);
				wordTemplate.process(map, wordWrite);
				wordWrite.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.free(connection);
		}
	}
	
}
